// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
//==========================================================================
//  File:       BaseTransportHeaders.cs 
// 
//  Summary:    Base class for special-cased transport headers implementations.
// 
//=========================================================================


using System; 
using System.Collections;
using System.Globalization; 
using System.Net; 

 
namespace System.Runtime.Remoting.Channels
{

    [Serializable] 
    internal class BaseTransportHeaders : ITransportHeaders
    { 
        // IMPORTANT: If a new wellknown header is added, MapHeaderNameToIndex, 
        //   GetValueFromHeaderIndex, and SetValueFromHeaderIndex methods must
        //   be updated (as well as WellknownHeaderCount)!!! 

        internal const int WellknownHeaderCount = 4;

        private Object _connectionId; // 0) CommonTransportKeys.ConnectionId 
        private Object _ipAddress;    // 1) CommonTransportKeys.IPAddress
 
        private String _requestUri;   // 2) CommonTransportKeys.RequestUri 
        private String _contentType;  // 3) "Content-Type"
 

        // transport headers structure is for non well-known headers
        private ITransportHeaders _otherHeaders;
 

        public BaseTransportHeaders() 
        { 
            _otherHeaders = null;
        } 


        public String RequestUri
        { 
            get { return _requestUri; }
            set { _requestUri = value; } 
        } // RequestUri 

 
        public String ContentType
        {
            get { return _contentType; }
            set { _contentType = value; } 
        } // ContentType
 
 
        public Object ConnectionId
        { 
            set { _connectionId = value; }
        }

        public IPAddress IPAddress 
        {
            set { _ipAddress = value; } 
        } 

 
        //
        // ITransportHeaders implementation
        //
 
        public Object this[Object key]
        { 
            get 
            {
                String strKey = key as String; 
                if (strKey != null)
                {
                    int index = MapHeaderNameToIndex(strKey);
                    if (index != -1) 
                        return GetValueFromHeaderIndex(index);
                } 
 
                if (_otherHeaders != null)
                    return _otherHeaders[key]; 

                return null;
            } // get
 
            set
            { 
                bool bSet = false; 

                String strKey = key as String; 
                if (strKey != null)
                {
                    int index = MapHeaderNameToIndex(strKey);
                    if (index != -1) 
                    {
                        SetValueFromHeaderIndex(index, value); 
                        bSet = true; 
                    }
                } 

                if (!bSet)
                {
                    if (_otherHeaders == null) 
                        _otherHeaders = new TransportHeaders();
                    _otherHeaders[key] = value; 
                } 
            } // set
        } // Object this[Object key] 


        public IEnumerator GetEnumerator()
        { 
            return new BaseTransportHeadersEnumerator(this);
        } // GetEnumerator 
 

        internal IEnumerator GetOtherHeadersEnumerator() 
        {
            if (_otherHeaders == null)
                return null;
 
            return _otherHeaders.GetEnumerator();
        } // GetOtherHeadersEnumerator 
 

 
        internal int MapHeaderNameToIndex(String headerName)
        {
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri
            // 3) "Content-Type" 
 
            if (String.Compare(headerName, CommonTransportKeys.ConnectionId, StringComparison.OrdinalIgnoreCase) == 0)
                return 0; 
            else
            if (String.Compare(headerName, CommonTransportKeys.IPAddress, StringComparison.OrdinalIgnoreCase) == 0)
                return 1;
            else 
            if (String.Compare(headerName, CommonTransportKeys.RequestUri, StringComparison.OrdinalIgnoreCase) == 0)
                return 2; 
            else 
            if (String.Compare(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase) == 0)
                return 3; 

            return -1;
        } // MapHeaderNameToIndex
 

        internal String MapHeaderIndexToName(int index) 
        { 
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri
            // 3) "Content-Type"

            switch (index) 
            {
            case 0: return CommonTransportKeys.ConnectionId; 
            case 1: return CommonTransportKeys.IPAddress; 
            case 2: return CommonTransportKeys.RequestUri;
            case 3: return "Content-Type"; 

            default: return null;
            }
 
        } // MapHeaderNameToIndex
 
 
        internal Object GetValueFromHeaderIndex(int index)
        { 
            // NOTE: If this method returns the null, then that indicates the header has no
            //   value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
            //   means that the header should be skipped.
 
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri 
            // 3) "Content-Type"
 
            switch (index)
            {
            case 0: return _connectionId;
            case 1: return _ipAddress; 
            case 2: return _requestUri;
            case 3: return _contentType; 
 
            default: return null;
            } 

        } // MapHeaderIndexToValue

 
        internal void SetValueFromHeaderIndex(int index, Object value)
        { 
            // NOTE: If this method returns the null, then that indicates the header has no 
            //   value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
            //   means that the header should be skipped. 

            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress
            // 2) CommonTransportKeys.RequestUri 
            // 3) "Content-Type"
 
            switch (index) 
            {
            case 0: _connectionId = value; break; 
            case 1: _ipAddress = value; break;
            case 2: _requestUri = (String)value; break;
            case 3: _contentType = (String)value; break;
 
            default:
            { 
                InternalRemotingServices.RemotingAssert(false, "someone forgot to update this method"); 
                break;
            } 

            } // switch (index)

        } // MapHeaderIndexToValue 

 
 
    } // class BaseTransportHeaders
 


    internal class BaseTransportHeadersEnumerator : IEnumerator
    { 
        private BaseTransportHeaders _headers;
        private bool _bStarted; 
        private int _currentIndex; 
        private IEnumerator _otherHeadersEnumerator;
 
        public BaseTransportHeadersEnumerator(BaseTransportHeaders headers)
        {
            _headers = headers;
            Reset(); 
        } // BaseTransportHeadersEnumerator
 
 
        public bool MoveNext()
        { 
            if (_currentIndex != -1)
            {
                if (_bStarted)
                    _currentIndex++; 
                else
                    _bStarted = true; 
 
                while (_currentIndex != -1)
                { 
                    if (_currentIndex >= BaseTransportHeaders.WellknownHeaderCount)
                    {
                        _otherHeadersEnumerator = _headers.GetOtherHeadersEnumerator();
                        _currentIndex = -1; 
                    }
                    else 
                    { 
                        if (_headers.GetValueFromHeaderIndex(_currentIndex) != null)
                            return true; 

                        _currentIndex++;
                    }
                } 
            }
 
            if (_otherHeadersEnumerator != null) 
            {
                if (!_otherHeadersEnumerator.MoveNext()) 
                {
                    _otherHeadersEnumerator = null;
                    return false;
                } 
                else
                    return true; 
            } 

            return false; 
        } // MoveNext

        public void Reset()
        { 
            _bStarted = false;
            _currentIndex = 0; 
            _otherHeadersEnumerator = null; 
        } // Reset
 
        public Object Current
        {
            get
            { 
                if (!_bStarted)
                    return null; 
 
                if (_currentIndex != -1)
                { 
                    return
                        new DictionaryEntry(
                            _headers.MapHeaderIndexToName(_currentIndex),
                            _headers.GetValueFromHeaderIndex(_currentIndex)); 
                }
 
                if (_otherHeadersEnumerator != null) 
                {
                    return _otherHeadersEnumerator.Current; 
                }

                return null;
            } 
        } // Current
 
    } // class BaseTransportHeadersEnumerator 

 


} // namespace System.Runtime.Remoting.Channels

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
//==========================================================================
//  File:       BaseTransportHeaders.cs 
// 
//  Summary:    Base class for special-cased transport headers implementations.
// 
//=========================================================================


using System; 
using System.Collections;
using System.Globalization; 
using System.Net; 

 
namespace System.Runtime.Remoting.Channels
{

    [Serializable] 
    internal class BaseTransportHeaders : ITransportHeaders
    { 
        // IMPORTANT: If a new wellknown header is added, MapHeaderNameToIndex, 
        //   GetValueFromHeaderIndex, and SetValueFromHeaderIndex methods must
        //   be updated (as well as WellknownHeaderCount)!!! 

        internal const int WellknownHeaderCount = 4;

        private Object _connectionId; // 0) CommonTransportKeys.ConnectionId 
        private Object _ipAddress;    // 1) CommonTransportKeys.IPAddress
 
        private String _requestUri;   // 2) CommonTransportKeys.RequestUri 
        private String _contentType;  // 3) "Content-Type"
 

        // transport headers structure is for non well-known headers
        private ITransportHeaders _otherHeaders;
 

        public BaseTransportHeaders() 
        { 
            _otherHeaders = null;
        } 


        public String RequestUri
        { 
            get { return _requestUri; }
            set { _requestUri = value; } 
        } // RequestUri 

 
        public String ContentType
        {
            get { return _contentType; }
            set { _contentType = value; } 
        } // ContentType
 
 
        public Object ConnectionId
        { 
            set { _connectionId = value; }
        }

        public IPAddress IPAddress 
        {
            set { _ipAddress = value; } 
        } 

 
        //
        // ITransportHeaders implementation
        //
 
        public Object this[Object key]
        { 
            get 
            {
                String strKey = key as String; 
                if (strKey != null)
                {
                    int index = MapHeaderNameToIndex(strKey);
                    if (index != -1) 
                        return GetValueFromHeaderIndex(index);
                } 
 
                if (_otherHeaders != null)
                    return _otherHeaders[key]; 

                return null;
            } // get
 
            set
            { 
                bool bSet = false; 

                String strKey = key as String; 
                if (strKey != null)
                {
                    int index = MapHeaderNameToIndex(strKey);
                    if (index != -1) 
                    {
                        SetValueFromHeaderIndex(index, value); 
                        bSet = true; 
                    }
                } 

                if (!bSet)
                {
                    if (_otherHeaders == null) 
                        _otherHeaders = new TransportHeaders();
                    _otherHeaders[key] = value; 
                } 
            } // set
        } // Object this[Object key] 


        public IEnumerator GetEnumerator()
        { 
            return new BaseTransportHeadersEnumerator(this);
        } // GetEnumerator 
 

        internal IEnumerator GetOtherHeadersEnumerator() 
        {
            if (_otherHeaders == null)
                return null;
 
            return _otherHeaders.GetEnumerator();
        } // GetOtherHeadersEnumerator 
 

 
        internal int MapHeaderNameToIndex(String headerName)
        {
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri
            // 3) "Content-Type" 
 
            if (String.Compare(headerName, CommonTransportKeys.ConnectionId, StringComparison.OrdinalIgnoreCase) == 0)
                return 0; 
            else
            if (String.Compare(headerName, CommonTransportKeys.IPAddress, StringComparison.OrdinalIgnoreCase) == 0)
                return 1;
            else 
            if (String.Compare(headerName, CommonTransportKeys.RequestUri, StringComparison.OrdinalIgnoreCase) == 0)
                return 2; 
            else 
            if (String.Compare(headerName, "Content-Type", StringComparison.OrdinalIgnoreCase) == 0)
                return 3; 

            return -1;
        } // MapHeaderNameToIndex
 

        internal String MapHeaderIndexToName(int index) 
        { 
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri
            // 3) "Content-Type"

            switch (index) 
            {
            case 0: return CommonTransportKeys.ConnectionId; 
            case 1: return CommonTransportKeys.IPAddress; 
            case 2: return CommonTransportKeys.RequestUri;
            case 3: return "Content-Type"; 

            default: return null;
            }
 
        } // MapHeaderNameToIndex
 
 
        internal Object GetValueFromHeaderIndex(int index)
        { 
            // NOTE: If this method returns the null, then that indicates the header has no
            //   value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
            //   means that the header should be skipped.
 
            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress 
            // 2) CommonTransportKeys.RequestUri 
            // 3) "Content-Type"
 
            switch (index)
            {
            case 0: return _connectionId;
            case 1: return _ipAddress; 
            case 2: return _requestUri;
            case 3: return _contentType; 
 
            default: return null;
            } 

        } // MapHeaderIndexToValue

 
        internal void SetValueFromHeaderIndex(int index, Object value)
        { 
            // NOTE: If this method returns the null, then that indicates the header has no 
            //   value (i.e. isn't in the "dictionary"). For the purposes of iteration, this
            //   means that the header should be skipped. 

            // 0) CommonTransportKeys.ConnectionId
            // 1) CommonTransportKeys.IPAddress
            // 2) CommonTransportKeys.RequestUri 
            // 3) "Content-Type"
 
            switch (index) 
            {
            case 0: _connectionId = value; break; 
            case 1: _ipAddress = value; break;
            case 2: _requestUri = (String)value; break;
            case 3: _contentType = (String)value; break;
 
            default:
            { 
                InternalRemotingServices.RemotingAssert(false, "someone forgot to update this method"); 
                break;
            } 

            } // switch (index)

        } // MapHeaderIndexToValue 

 
 
    } // class BaseTransportHeaders
 


    internal class BaseTransportHeadersEnumerator : IEnumerator
    { 
        private BaseTransportHeaders _headers;
        private bool _bStarted; 
        private int _currentIndex; 
        private IEnumerator _otherHeadersEnumerator;
 
        public BaseTransportHeadersEnumerator(BaseTransportHeaders headers)
        {
            _headers = headers;
            Reset(); 
        } // BaseTransportHeadersEnumerator
 
 
        public bool MoveNext()
        { 
            if (_currentIndex != -1)
            {
                if (_bStarted)
                    _currentIndex++; 
                else
                    _bStarted = true; 
 
                while (_currentIndex != -1)
                { 
                    if (_currentIndex >= BaseTransportHeaders.WellknownHeaderCount)
                    {
                        _otherHeadersEnumerator = _headers.GetOtherHeadersEnumerator();
                        _currentIndex = -1; 
                    }
                    else 
                    { 
                        if (_headers.GetValueFromHeaderIndex(_currentIndex) != null)
                            return true; 

                        _currentIndex++;
                    }
                } 
            }
 
            if (_otherHeadersEnumerator != null) 
            {
                if (!_otherHeadersEnumerator.MoveNext()) 
                {
                    _otherHeadersEnumerator = null;
                    return false;
                } 
                else
                    return true; 
            } 

            return false; 
        } // MoveNext

        public void Reset()
        { 
            _bStarted = false;
            _currentIndex = 0; 
            _otherHeadersEnumerator = null; 
        } // Reset
 
        public Object Current
        {
            get
            { 
                if (!_bStarted)
                    return null; 
 
                if (_currentIndex != -1)
                { 
                    return
                        new DictionaryEntry(
                            _headers.MapHeaderIndexToName(_currentIndex),
                            _headers.GetValueFromHeaderIndex(_currentIndex)); 
                }
 
                if (_otherHeadersEnumerator != null) 
                {
                    return _otherHeadersEnumerator.Current; 
                }

                return null;
            } 
        } // Current
 
    } // class BaseTransportHeadersEnumerator 

 


} // namespace System.Runtime.Remoting.Channels

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
